package cn.hloger.spider.utils;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * 集合排序,交集,差集,转化工具类
 *
 * @author hlong
 * @ClassName: ArrayUtils
 * @Description: 集合排序, 交集, 差集工具类
 * @date 2019年9月26日
 */

public class ArrayUtils {

    /**
     * list 求差集
     *
     * @param n
     * @param m
     * @param <T>
     * @return
     */
    public static <T> List<T> getDifferenceSet(List<T> n, List<T> m) {
        //转化最长列表
        Set<T> set = new HashSet<>(n.size() > m.size() ? n : m);
        //循环最短列表
        for (T t : n.size() > m.size() ? m : n) {
            if (set.contains(t)) {
                set.remove(t);
            } else {
                set.add(t);
            }
        }
        return new ArrayList<T>(set);
    }

    /**
     * list 求交集
     *
     * @param n
     * @param m
     * @param <T>
     * @return
     */
    public static <T> List getIntersection(List<T> n, List<T> m) {
        Set<T> setN = new HashSet<>(n);
        Set<T> setM = new HashSet<>(m);
        setN.retainAll(setM);
        return new ArrayList(setN);
    }


    /**
     * list 集合并集
     *
     * @param n
     * @param m
     * @param <T>
     * @return
     */
    public static <T> List<T> getUnion(List<T> n, List<T> m) {
        Set<T> setN = new HashSet<>(n);
        Set<T> setM = new HashSet<>(m);
        setN.addAll(setM);
        return new ArrayList<T>(setN);
    }

    /**
     * 数组求差集
     *
     * @param n
     * @param m
     * @param <T>
     * @return
     */
    public static <T> T[] getDifferenceSet(T[] n, T[] m) {
        List<T> list = ArrayUtils.getDifferenceSet(Arrays.asList(n), Arrays.asList(m));
        return list.toArray(Arrays.copyOf(n, list.size()));
    }

    /**
     * 数组求交集
     *
     * @param n
     * @param m
     * @param <T>
     * @return
     */
    public static <T> T[] getIntersection(T[] n, T[] m) {
        List<T> list = ArrayUtils.getIntersection(Arrays.asList(n), Arrays.asList(m));
        return list.toArray(Arrays.copyOf(n, list.size()));
    }

    /**
     * 数组并集
     *
     * @param n
     * @param m
     * @param <T>
     * @return
     */
    public static <T> T[] getUnion(T[] n, T[] m) {
        List<T> list = getUnion(Arrays.asList(n), Arrays.asList(m));
        return list.toArray(Arrays.copyOf(n, list.size()));

    }


    /**
     * 字符串转化为int的数组
     *
     * @param a
     * @return
     */
    public static int[] strArrayToIntArray(String[] a) {
        int[] b = new int[a.length];
        for (int i = 0; i < a.length; i++) {
            b[i] = Integer.parseInt(a[i]);
        }
        return b;

    }

    /**
     * 字符串转化为Long的数组
     *
     * @param a
     * @return
     */
    public static Long[] strArrayToLongArray(String[] a) {
        Long[] b = new Long[a.length];
        for (int i = 0; i < a.length; i++) {
            b[i] = Long.parseLong(a[i]);
        }
        return b;
    }


    /**
     * 数组转为字符串  如 int[]={1.2.3}   转化为 String xx = "1,2,3"
     *
     * @param arr
     * @return
     */
    public static String arrToString(List arr) {
        StringBuilder str = new StringBuilder();
        if (null == arr || arr.size() == 0) {
            return str.toString();
        }
        for (int i = 0; i < arr.size(); i++) {
            if (i == 0) {
                str.append(arr.get(i).toString());
            } else {
                str.append(",").append(arr.get(i).toString());
            }
        }
        return str.toString();
    }


    /**
     * 字符串每3个字符切割成一个list
     *
     * @return 返回类型
     * @throws
     * @author hlong
     */
    public static List<Long> strToLongArrayFor3(String str) {
        List<Long> list = new ArrayList();
        for (int i = 0; i < str.length(); i = i + 3) {
            String x = "";
            if (i + 3 > str.length()) {
                x = str.substring(i, str.length());
            } else {
                x = str.substring(i, i + 3);
            }
            list.add(Long.valueOf(x));
        }
        return list;
    }


    /**
     * 给指定scores，算出每个score的排名
     *
     * @param scores
     * @return Map<Double, Integer>
     */
    public static Map<Double, Integer> calculateScoreRankMap(List<Double> scores) {
        Map<Double, Integer> scoreRankMap = new HashMap<>();
        //按分数倒序排列
        scores.sort(Comparator.comparingDouble(Double::doubleValue).reversed());
        //按分数分组，统计个数
        Map<Double, Long> scoreMap = scores.stream().collect(Collectors.groupingBy(Double::doubleValue, Collectors.counting()));
        //初始值名次
        int rank = 1;
        for (int i = 0; i < scores.size(); i++) {
            scoreRankMap.put(scores.get(i), rank);
            //得到相同分数的个数
            Long count = scoreMap.get(scores.get(i));
            if (count == 1) {
                rank++;
            } else {
                //排名还需要按人数顺序数他是第几个
                rank = (int) (rank + count);
                //连续n个相同的总分，排名一样
                i = (int) (i + count - 1);
            }
        }
        return scoreRankMap;
    }


    /**
     * object对象转数组
     *
     * @param object
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> obj2List(Object object, Class<T> clazz) {
        List<T> list = new ArrayList<T>();
        if (object instanceof ArrayList<?>) {
            for (Object o : (List<?>) object) {
                list.add(clazz.cast(o));
            }
            return list;
        }
        return null;
    }


    public static void main(String[] args) {
        List<Integer> list1 = new ArrayList();
        list1.add(1);
        list1.add(2);
        list1.add(3);
        list1.add(4);
        list1.add(5);
        list1.add(6);
        List<Integer> list2 = new ArrayList();
        list2.add(4);
        list2.add(5);
        list2.add(6);
        list2.add(7);
        list2.add(8);
        list2.add(9);
        List<Integer> union = getIntersection(list1, list2); //得到两个集合相同对象的集合
        for (Object object : union) {
            System.out.println(object);
        }
    }

}